﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace NAntExt
{
    public class ParallelContext
    {
        public const string DefaultContextKey = "";
        public static TDictionary<string, ParallelContext> Contexts = new TDictionary<string, ParallelContext>();

        public static ParallelContext GetContext(string contextKey)
        {
            if (contextKey == null)
            {
                throw new ArgumentNullException("contextKey");
            }
            else if (contextKey == string.Empty)
            {
                throw new ArgumentOutOfRangeException("contextKey", "Value cannot be empty.");
            }

            if (Contexts.ContainsKey(contextKey))
            {
                return Contexts[contextKey];
            }
            else
            {
                return null;
            }
        }

        private TQueue<ParallelTask> QueuedThreads = new TQueue<ParallelTask>();
        private ReaderWriterLockSlim QueuedThreadsLock = new ReaderWriterLockSlim();

        public int GetQueuedThreadCount()
        {
            QueuedThreadsLock.EnterReadLock();
            try
            {
                return QueuedThreads.Count;
            }
            finally
            {
                QueuedThreadsLock.ExitReadLock();
            }
        }

        public void Enqueue(ParallelTask thread)
        {
            QueuedThreadsLock.EnterWriteLock();
            try
            {
                QueuedThreads.Enqueue(thread);
            }
            finally
            {
                QueuedThreadsLock.ExitWriteLock();
            }
        }

        public ParallelTask Dequeue()
        {
            QueuedThreadsLock.EnterWriteLock();
            try
            {
                if (QueuedThreads.Count > 0)
                {
                    return QueuedThreads.Dequeue();
                }
                else
                {
                    return null;
                }
            }
            finally
            {
                QueuedThreadsLock.ExitWriteLock();
            }
        }
    }
}